package com.soul.server.server;

import com.soul.commons.exception.SoulGlobalException;
import com.soul.dubbo.api.db.QuestionnaireApi;
import com.soul.dubbo.api.db.QuestionsApi;
import com.soul.dubbo.api.db.UserInfoApi;
import com.soul.dubbo.api.mongo.SoulApi;
import com.soul.model.db.Question;
import com.soul.model.db.UserInfo;
import com.soul.model.dto.QuestionDto;
import com.soul.model.mongo.*;
import com.soul.model.vo.*;
import com.soul.server.utils.UserHolder;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang3.RandomUtils;
import org.apache.dubbo.config.annotation.DubboReference;
import org.bson.types.ObjectId;
import org.checkerframework.checker.units.qual.A;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author mdoya
 * @version 1.0
 * @description:
 */
@Slf4j
@Service
public class TestSoulService {

    @DubboReference
    private SoulApi soulApi;

    @DubboReference
    private QuestionsApi questionsApi;

    @DubboReference
    private QuestionnaireApi questionnaireApi;

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @DubboReference
    private UserInfoApi userInfoApi;

    /**
     * 测灵魂-提交问卷
     *
     * @return 最新报告id
     */
    public String addSoul(List<QuestionDto> questionDtoList) {
        // 1. 当前用户id
        Long currendUserId = UserHolder.getUserId();
        if (CollectionUtils.isEmpty(questionDtoList)) throw new SoulGlobalException(ErrorResult.error());
        // 2. 查询选项题累加分数
        List<ObjectId> OptionIds = questionDtoList.stream().map((questionDto)->{
            return new ObjectId(questionDto.getOptionId());
        }).collect(Collectors.toList());
        Integer score = soulApi.findQuestionByIds(OptionIds);
        String level = "";
        for (QuestionDto questionDto : questionDtoList) {
            Questions questions = soulApi.findQuestionLevel(questionDto.getQuestionId()); // 查询题目级别
            level = questions.getLevel();
            break; // 拿到级别字段值结束本次循环
        }
        if ("初级".equals(level)){ // 初级
            return addAndUpdateReport(currendUserId, score, level);
        } else if ("中级".equals(level)){ // 中级
            return addAndUpdateReport(currendUserId, score, level);
        }
        // 高级
        return addAndUpdateReport(currendUserId, score, level);
    }

    /**
     *  新增和修改最新报告
     * @param currendUserId
     * @param score
     * @param level
     * @return
     */
    private String addAndUpdateReport(Long currendUserId, Integer score, String level) {
        Report report = null;
        if (score >= 8 && score <= 10){ // 8 10 // 兔子型
            report = soulApi.findReportExits(currendUserId, level); // 当前用户和级别查询当前用户是否已经测试过
            if (report != null){ // 修改报告
                report = commonField(report,currendUserId, score, level,true); // 修改公共字段
                return report.getId().toHexString();
            }
            // 新增报告
            report = commonField(report,currendUserId, score, level,false); // 新增或修改公共字段
            report.setType(3); // 鉴定类型 狮子型 猫头鹰 兔子型 狐狸型  1  2  3  4
            report.setConclusion("白兔型：平易近人、敦厚可靠、避免冲突与不具批判性。在行为上，表现出不慌不忙、冷静自持的态度。他们注重稳定与中长程规划，现实生活中，常会反思自省并以和谐为中心，即使面对困境，亦能泰然自若，从容应付。");
            report.setCover("https://tanhua-dev.oss-cn-zhangjiakou.aliyuncs.com/images/test_soul/rabbit.png");
            report.setExtroversion("外向");
            soulApi.addReport(report);
            return report.getId().toHexString(); // 返回最新报告id
        } else if (score >= 11 && score <= 13){ // 11 13 // 狮子型
            report = soulApi.findReportExits(currendUserId, level); // 当前用户和级别查询当前用户是否已经测试过
            if (report != null){ // 修改报告
                report = commonField(report,currendUserId, score, level,true); // 修改公共字段
                return report.getId().toHexString();
            }
            report = commonField(report,currendUserId, score, level,false); // 新增或修改公共字段
            report.setType(1); // 鉴定类型 狮子型 猫头鹰 兔子型  1  2  3  4
            report.setConclusion("狮子型：性格为充满自信、竞争心强、主动且企图心强烈，是个有决断力的领导者。一般而言，狮子型的人胸怀大志，勇于冒险，看问题能够直指核心，并对目标全力以赴。他们在领导风格及决策上，强调权威与果断，擅长危机处理，此种性格最适合开创性与改革性的工作。");
            report.setCover("https://tanhua-dev.oss-cn-zhangjiakou.aliyuncs.com/images/test_soul/lion.png");
            report.setExtroversion("活泼");
            soulApi.addReport(report);
            return report.getId().toHexString(); // 返回最新报告id
        } else if (score >= 14 && score <= 16){ // 14 16  猫头鹰
            report = soulApi.findReportExits(currendUserId, level); // 当前用户和级别查询当前用户是否已经测试过
            if (report != null){ // 修改报告
                report = commonField(report,currendUserId, score, level,true); // 修改公共字段
                return report.getId().toHexString();
            }
            report = commonField(report,currendUserId, score, level,false); // 新增或修改公共字段
            report.setType(2); // 鉴定类型 狮子型 猫头鹰 兔子型 狐狸型  1  2  3  4
            report.setConclusion("猫头鹰：他们的共同特质为重计划、条理、细节精准。在行为上，表现出喜欢理性思考与分析、较重视制度、结构、规范。他们注重执行游戏规则、循规蹈矩、巨细靡遗、重视品质、敬业负责。");
            report.setCover("https://tanhua-dev.oss-cn-zhangjiakou.aliyuncs.com/images/test_soul/owl.png");
            report.setExtroversion("外向");
            soulApi.addReport(report);
            return report.getId().toHexString(); // 返回最新报告id
        }
        report = soulApi.findReportExits(currendUserId, level); // 当前用户和级别查询当前用户是否已经测试过
        if (report != null){ // 修改报告
            report = commonField(report,currendUserId, score, level,true); // 修改公共字段
            return report.getId().toHexString();
        }
        // 17  20  狐狸型
        report = commonField(report,currendUserId, score, level,false); // 新增或修改公共字段
        report.setType(4); // 鉴定类型 狮子型 猫头鹰 兔子型 狐狸型  1  2  3  4
        report.setConclusion("狐狸型：人际关系能力极强，擅长以口语表达感受而引起共鸣，很会激励并带动气氛。他们喜欢跟别人互动，重视群体的归属感，基本上是比较「人际导向」。由于他们富同理心并乐于分享，具有很好的亲和力，在服务业、销售业、传播业及公共关系等领域中，狐狸型的领导者都有很杰出的表现。");
        report.setCover("https://tanhua-dev.oss-cn-zhangjiakou.aliyuncs.com/images/test_soul/fox.png");
        report.setExtroversion("内向");
        soulApi.addReport(report);
        return report.getId().toHexString(); // 返回最新报告id
    }

    private Report commonField(Report report,Long currendUserId, Integer score, String level,Boolean au) {
        Long nowTime = System.currentTimeMillis();
        if (au){ // 修改
            report.setUserId(currendUserId);
            report.setUpdated(nowTime);
            report.setScope(score);
            soulApi.updateReport(report);
            return report;
        }
        // 新增
        report = new Report();
        report.setUserId(currendUserId);
        report.setCreated(nowTime);
        report.setUpdated(nowTime);
        report.setScope(score);
        report.setLevel(level);
        report.setId(ObjectId.get());
        return report;
    }

    /**
     * 测灵魂-查看结果
     *
     * @param reportId 报告id
     * @return TestSoulVo
     */
    public ReportVo findReportResult(String reportId) {
        // 1. 校验最新报告id
        if (StringUtils.isEmpty(reportId)) {
            throw new SoulGlobalException("还没有灵魂测试报告");
        }
        // 2. 查询灵魂测试报告
        Report report = soulApi.findReportById(reportId);
        // 2.1 没有查询最新报告
        if (report != null) {
            ReportVo reportVo = getReportVo(report);
            // 与你相似
            reportVo.setSimilarYou(randomUser(userInfoApi.findByUserIdUser(UserHolder.getUserId()))); // 与你相似   key:id （Integer）、avatar(String)  value:用户编号、头像
            System.err.println("最新报告 = " + reportVo);
            return reportVo;
        }
        return null;
    }

    // 模拟用户维度
    private ReportVo getReportVo(Report report) {
        ReportVo reportVo = new ReportVo();
        BeanUtils.copyProperties(report,reportVo);
        List<DimensionsVo> dimensionsVoList = new ArrayList<>();
        DimensionsVo dimensionsVo = new DimensionsVo();
        dimensionsVo.setKey("外向"); // key:维度项 枚举: 外向,判断,抽象,理性  value:维度值 枚举: 80%,70%,90%,60%
        dimensionsVo.setValue("80%"); //  维度值 80%,70%,90%,60%
        dimensionsVoList.add(dimensionsVo);
        DimensionsVo dimensionsVo2 = new DimensionsVo();
        dimensionsVo2.setKey("判断"); // key:维度项 枚举: 外向,判断,抽象,理性  value:维度值 枚举: 80%,70%,90%,60%
        dimensionsVo2.setValue("70%"); //  维度值 80%,70%,90%,60%
        dimensionsVoList.add(dimensionsVo2);
        DimensionsVo dimensionsVo3 = new DimensionsVo();
        dimensionsVo3.setKey("抽象"); // key:维度项 枚举: 外向,判断,抽象,理性  value:维度值 枚举: 80%,70%,90%,60%
        dimensionsVo3.setValue("90%"); //  维度值 80%,70%,90%,60%
        dimensionsVoList.add(dimensionsVo3);
        DimensionsVo dimensionsVo4 = new DimensionsVo();
        dimensionsVo4.setKey("理性"); // key:维度项 枚举: 外向,判断,抽象,理性  value:维度值 枚举: 80%,70%,90%,60%
        dimensionsVo4.setValue("60%"); //  维度值 80%,70%,90%,60%
        dimensionsVoList.add(dimensionsVo4);
        reportVo.setDimensions(dimensionsVoList); // 维度
        return reportVo;
    }

    // 查询随机与你相似用户
    public List<SimilarYouVo> randomUser(UserInfo u) {
        List<SimilarYouVo> similarYouVoList = new ArrayList<>();
        // 1. 查询用户总条数
        List<UserInfo> userInfoList = userInfoApi.findUserInfoAll();
        for (int i = 0; i <= 20; i++) {
            int userId = RandomUtils.nextInt(0, userInfoList.size() - 1);
            UserInfo userInfo = userInfoApi.findByUserIdUser(Long.valueOf(userId));
            // 当前用户u对象   与你相似用户userInfo对象  非自己  非同性别
            if (userInfo != null && !u.getGender().equals(userInfo.getGender()) && u.getId() != userInfo.getId()){
                SimilarYouVo similarYouVo = new SimilarYouVo();
                similarYouVo.setId(userInfo.getId().intValue());
                similarYouVo.setAvatar(userInfo.getAvatar());
                similarYouVoList.add(similarYouVo);
            }
        }
        return similarYouVoList;
    }

    private void moniNew() {
        ReportVo reportVo = new ReportVo();
        reportVo.setConclusion("狮子型：性格为充满自信、竞争心强、主动且企图心强烈，是个有决断力的领导者。一般而言，狮子型的人胸怀大志，勇于冒险，看问题能够直指核心，并对目标全力以赴。他们在领导风格及决策上，强调权威与果断，擅长危机处理，此种性格最适合开创性与改革性的工作。"); // 鉴定结果
        reportVo.setCover("https://tanhua-dev.oss-cn-zhangjiakou.aliyuncs.com/images/test_soul/lion.png"); // 鉴定图片
        Map<String, String> dimensions = new HashMap<>();
        dimensions.put("key", "外向"); // 维度项（外向，判断，抽象，理性）
        dimensions.put("value", "80%"); // 枚举: 80%,70%,90%,60%
//        reportVo.setDimensions(dimensions); // 维度   key:维度项 枚举: 外向,判断,抽象,理性  value:维度值 枚举: 80%,70%,90%,60%

        Map<String, String> similarYou = new HashMap<>();
        similarYou.put("id", "1003"); // 维度项（外向，判断，抽象，理性）
        similarYou.put("avatar", "https://tanhua-dev.oss-cn-zhangjiakou.aliyuncs.com/images/tanhua/avatar_4.png"); // 枚举: 80%,70%,90%,60%
//        reportVo.setSimilarYou(similarYou); // 与你相似   key:id （Integer）、avatar(String)  value:用户编号、头像
    }

    /**
     * 测灵魂-问卷列表
     *
     * @return PageResult<SoulVo>
     */
    public List<SoulVo> testSoul() {
        // 1. 查询问卷列表
//        SoulVo soulVo = null;
        // 1.1 查询QuestionCover集合所有封面
        // 封面
        List<SoulVo> soulVoList = soulApi.findQuestionCover().stream().map((item) -> {
            SoulVo soulVo = new SoulVo();
            soulVo.setId(item.getId().toHexString());
            BeanUtils.copyProperties(item, soulVo);
            // 查询所有题目并遍历
            List<QuestionsVo> questionsVoList = soulApi.findQuestionsOne(item.getLevel()).stream().map((questions) -> {
                QuestionsVo questionsVo = new QuestionsVo();
                BeanUtils.copyProperties(questions, questionsVo);
                questionsVo.setId(questions.getId().toHexString());
                // 选项题 StackOverflowError溢出
                List<Options> optionsList = soulApi.findOptionsOne(questionsVo.getId());
                List<OptionsVo> optionsVoList = optionsList.stream().map((option) -> {
                    OptionsVo optionsVo = new OptionsVo();
                    BeanUtils.copyProperties(option, optionsVo);
                    optionsVo.setId(option.getId().toHexString());
                    return optionsVo;
                }).collect(Collectors.toList());
                questionsVo.setOptions(optionsVoList);
                return questionsVo;
            }).collect(Collectors.toList());
            soulVo.setQuestions(questionsVoList); // 查询题目结果并且添加到集合
            // 查询当前用户等级最新报告
            Report report = soulApi.findReportList(UserHolder.getUserId(), item.getLevel());
            if (report != null && StringUtils.isNotEmpty(report.getId().toHexString())) {
                String reportId = report.getId().toHexString();
                soulVo.setReportId(reportId);
                soulVo.setIsLock(0); // 有最新报告开启卡片
            }
            if (StringUtils.isEmpty(report.getId().toHexString()) && "中级".equals(report.getLevel())){ // 要继续完善
                soulVo.setIsLock(0); // 有最新报告开启卡片
            }
            return soulVo;
        }).collect(Collectors.toList());
        System.out.println("**********************************************************");
        soulVoList.stream().forEach(System.err::println);
        System.out.println("**********************************************************");
        return soulVoList;
    }
}
